package cz.muni.fi.pa165.sportclubmanager.web;

import cz.muni.fi.pa165.sportclubmanager.dto.AgeCategoryDTO;
import cz.muni.fi.pa165.sportclubmanager.service.AgeCategoryService;
import java.util.List;
import net.sourceforge.stripes.action.*;
import net.sourceforge.stripes.controller.LifecycleStage;
import net.sourceforge.stripes.integration.spring.SpringBean;
import net.sourceforge.stripes.validation.LocalizableError;
import net.sourceforge.stripes.validation.SimpleError;
import net.sourceforge.stripes.validation.Validate;
import net.sourceforge.stripes.validation.ValidateNestedProperties;
import net.sourceforge.stripes.validation.ValidationErrors;
import org.springframework.orm.jpa.JpaSystemException;

/**
 * ActionBean for AgeCategoryService
 *
 * @author mprokes
 */
@UrlBinding("/a/{$event}/{ageCategory.id}")
public class AgeCategoriesActionBean implements ActionBean {

    private static final String INDEX = "/agecategory/index.jsp";
    private static final String EDIT = "/agecategory/edit.jsp";    
    private ActionBeanContext context;
    @SpringBean
    protected AgeCategoryService ageCategoryService;
    @ValidateNestedProperties(value = {
        @Validate(on = {"add", "save"}, field = "name", required = true, maxlength = 255),
        @Validate(on = {"add", "save"}, field = "ageFrom", required = true, minvalue = 0, maxvalue = 150, expression = "ageCategory.ageFrom < ageCategory.ageTo"),
        @Validate(on = {"add", "save"}, field = "ageTo", required = true, minvalue = 1, maxvalue = 150)
    })
    private AgeCategoryDTO ageCategory;

    public AgeCategoryDTO getAgeCategory() {
        return ageCategory;
    }

    public void setAgeCategory(AgeCategoryDTO ageCategory) {
        this.ageCategory = ageCategory;
    }

    @Before(stages = LifecycleStage.BindingAndValidation, on = {"edit"})
    public void loadAgeCategoryFromDatabase() {
        String ids = context.getRequest().getParameter("ageCategory.id");
        if (ids == null) {
            return;
        }
        ageCategory = ageCategoryService.find(Long.parseLong(ids));
    }

    @DefaultHandler   
    public Resolution index() {
        return new ForwardResolution(INDEX);
    }

    public Resolution edit() {
        return new ForwardResolution(EDIT);
    }

    public Resolution save() {
        try {
            ageCategoryService.update(ageCategory);
            getContext().getMessages().add(new LocalizableMessage("ageCategory.action.save.success"));
        } catch (Exception exc) {
            return handleException(exc);
        }

        return new RedirectResolution(this.getClass(), "index");
    }
    
    
    public Resolution add() {
        try {
            ageCategoryService.create(ageCategory);
            getContext().getMessages().add(new LocalizableMessage("ageCategory.action.add.success"));
        } catch (Exception exc) {
            return handleException(exc) ;
        }
        return new RedirectResolution(this.getClass(), "index").flash(this);
    }

    public Resolution delete() {
        try {
            ageCategoryService.remove(ageCategory);
            getContext().getMessages().add(new LocalizableMessage("ageCategory.action.delete.success"));            
        } catch (Exception exc) {
            return handleException(exc) ;            
        }
        return new RedirectResolution(this.getClass(), "index");
    }

    /**
     * Translate Exceptions from service layer to message for user
     *
     * @param exc Throwed exception
     * @return Resolution to go
     */
    public Resolution handleException(Exception exc) {
        ValidationErrors errors = new ValidationErrors();

        if (exc.getClass() == IllegalArgumentException.class) {
            if (exc.getMessage().contains("bounds overlap")) {
                errors.add("ageCategory.ageFrom", new LocalizableError("ageCategory.exception.overlap"));
                errors.add("ageCategory.ageTo", new LocalizableError("ageCategory.exception.overlap"));
            } else {
                errors.addGlobalError(new SimpleError(exc.getLocalizedMessage()));
            }
            getContext().setValidationErrors(errors);
            return getContext().getSourcePageResolution();
        }
        if (exc.getClass() == JpaSystemException.class) {
            errors.addGlobalError(new LocalizableError("ageCategory.exception.constraint",exc.getLocalizedMessage()));
            getContext().setValidationErrors(errors);
            return getContext().getSourcePageResolution();
        }

        errors.addGlobalError(new SimpleError(exc.getClass()+" "+exc.getLocalizedMessage()));
        getContext().setValidationErrors(errors);
        return getContext().getSourcePageResolution();

    }
        

    public List<AgeCategoryDTO> getAgeCategories() {
        return ageCategoryService.findAll();
    }

    @Override
    public void setContext(ActionBeanContext context) {
        this.context = context;
    }

    @Override
    public ActionBeanContext getContext() {
        return context;
    }
}